# 导入数据处理相关库
import numpy as np
from sklearn.model_selection import train_test_split
raw_df = np.loadtxt("C:\\Users\\宿一凡\\Desktop\\room\ml-lesson\\03_dataset\\item3\\logi-y.txt", delimiter=',', encoding='utf-8') 
# 提取特征变量（科目1成绩、科目2成绩）
x = raw_df[:, [0, 1]]  # 取所有行，第0列和第1列
# 提取标签（是否录取）
y = raw_df[:, 2]       # 取所有行，第2列
# 划分训练集（70%）和测试集（30%）
x_train, x_test, y_train, y_test = train_test_split(
    x, y, test_size=0.3, random_state=42  # test_size=0.3 表示测试集占比30%
)
# 可选：查看数据形状，确认划分结果
print(f"训练集特征形状：{x_train.shape}")  # 输出格式如 (xx, 2)，xx为训练集样本数
print(f"测试集特征形状：{x_test.shape}")   # 输出格式如 (xx, 2)，xx为测试集样本数
# 导入逻辑回归模型和评估函数
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
# 初始化逻辑回归模型
model = LogisticRegression()
# 用训练集训练模型
model.fit(x_train, y_train)
# 可选：查看模型参数（系数w和截距b）
print(f"模型系数 w:{model.coef_}")  # 输出2个系数，对应科目1和科目2成绩的权重
print(f"模型截距 {model.intercept_}")  # 输出1个截距
# 用训练好的模型预测测试集标签
y_pred = model.predict(x_test)
# 计算预测准确率
accuracy = accuracy_score(y_test, y_pred)
# 输出评估结果
print(f"逻辑回归模型在测试集上的预测准确率：{accuracy:.2f}")  # 保留2位小数，如 0.85 表示85%准确率
# 导入绘图相关库
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
# 定义网格采样点数量（500×500）
N, M = 500, 500
# 生成科目1成绩的采样范围（根据原始数据调整，此处假设范围为 30~100 分）
x1_min, x1_max = x[:, 0].min() - 2, x[:, 0].max() + 2
t1 = np.linspace(x1_min, x1_max, N)
# 生成科目2成绩的采样范围（同理，假设范围为 60~90 分）
x2_min, x2_max = x[:, 1].min() - 2, x[:, 1].max() + 2
t2 = np.linspace(x2_min, x2_max, M)
# 生成网格点（x1为所有采样点的横坐标，x2为纵坐标）
x1, x2 = np.meshgrid(t1, t2)
# 将网格点转换为二维数组（每行对应一个采样点的两个特征）
x_grid = np.stack((x1.flat, x2.flat), axis=1)
# 预测所有网格点的类别
y_grid_pred = model.predict(x_grid)
# 调整预测结果形状，与网格点形状一致
y_grid_hat = y_grid_pred.reshape(x1.shape)
# 自定义分类边界颜色（不录取：浅绿 #ACF080；录取：浅蓝 #A0A0FF）
custom_cmap = ListedColormap(["#ACF080", "#A0A0FF"])
# 绘制分类边界
plt.pcolormesh(x1, x2, y_grid_hat, cmap=custom_cmap, alpha=0.5)  # alpha=0.5 调整透明度
# 绘制未录取样本点（标签0：蓝色圆点）
plt.scatter(
    x[y == 0, 0],  # 未录取样本的科目1成绩
    x[y == 0, 1],  # 未录取样本的科目2成绩
    s=50,          # 点的大小
    c='b',         # 颜色：蓝色
    marker='o',    # 形状：圆点
    label='未录取'  # 图例标签
)
# 绘制已录取样本点（标签1：红色三角）
plt.scatter(
    x[y == 1, 0],  # 已录取样本的科目1成绩
    x[y == 1, 1],  # 已录取样本的科目2成绩
    s=50,          # 点的大小
    c='r',         # 颜色：红色
    marker='^',    # 形状：三角
    label='已录取'  # 图例标签
)
# 设置中文字体（SimHei 为黑体）
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
# 设置横纵轴标签
plt.xlabel('科目1成绩', fontsize=12)
plt.ylabel('科目2成绩', fontsize=12)
# 设置标题
plt.title('招聘考试成绩逻辑回归分类结果', fontsize=14)
# 显示图例
plt.legend(fontsize=10)
# 显示图像
plt.show()